package com.yourenbang.lingyun.transaction.web.service.impl.pay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.enums.ChannelIdEnums;
import com.yourenbang.lingyun.constants.enums.FundBillType;
import com.yourenbang.lingyun.constants.enums.PayThreePartiesEnum;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.fund.AccountMainJournalType;
import com.yourenbang.lingyun.constants.enums.fund.AccountType;
import com.yourenbang.lingyun.constants.enums.pay.PayFromEnum;
import com.yourenbang.lingyun.constants.enums.pay.PayTypeEnum;
import com.yourenbang.lingyun.constants.enums.table.AllyTicketEnum;
import com.yourenbang.lingyun.constants.enums.table.MallOrderEnum;
import com.yourenbang.lingyun.core.exception.SysBizException;
import com.yourenbang.lingyun.core.exception.UserBizException;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.util.BizAssertUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.date.DateFormat;
import com.yourenbang.lingyun.core.util.date.LocalDateUtils;
import com.yourenbang.lingyun.core.util.encrypt.AesEncryptUtil;
import com.yourenbang.lingyun.domain.*;
import com.yourenbang.lingyun.mapper.*;
import com.yourenbang.lingyun.transaction.constant.ChangePlanStatus;
import com.yourenbang.lingyun.transaction.constant.ChangeTypeConstant;
import com.yourenbang.lingyun.transaction.exception.WichdrawFailException;
import com.yourenbang.lingyun.transaction.exception.WichdrawWaitException;
import com.yourenbang.lingyun.transaction.mapper.TransactionFundAccountChangePlanMapper;
import com.yourenbang.lingyun.transaction.web.domain.dto.ChangeFundAccountV2DTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.AlipayProperties;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.AlipayTradeQueryBiz;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.PayAttachParamDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.WechatPayDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.app.AliPayDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.app.AppPayDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.app.ToPupDTO;
import com.yourenbang.lingyun.transaction.web.domain.po.FundAccountChangePlan;
import com.yourenbang.lingyun.transaction.web.domain.vo.JournalInfoVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.pay.AppPayVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.pay.ToPupVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.pay.WxAppPayOrderVO;
import com.yourenbang.lingyun.transaction.web.service.CommonService;
import com.yourenbang.lingyun.transaction.web.service.fund.FundService;
import com.yourenbang.lingyun.transaction.web.service.pay.PayService;
import com.yourenbang.lingyun.transaction.web.service.pay.PayTypeService;
import com.yourenbang.mall.api.model.dto.MallOrderPaySuccessUpdateDTO;
import com.yourenbang.mall.api.service.MallOrderApiService;
import com.yourenbang.mcenter.api.service.McenterMessageService;
import com.yourenbang.merchant.api.model.dto.klks.DepositNoticeDTO;
import com.yourenbang.merchant.api.service.klks.MerchantPledgeApiService;
import com.yourenbang.transaction.api.model.dto.pay.TradeQueryDTO;
import com.yourenbang.transaction.api.model.dto.pay.TradeRefundDTO;
import com.yourenbang.transaction.api.model.vo.FundPayBusVO;
import com.yourenbang.transaction.api.service.pay.PayTypeApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service("payService")
public class PayServiceImpl implements PayService {

    @Autowired
    private UserBaseMapper userBaseMapper;
    @Autowired
    private PayThreePartiesMapper payThreePartiesMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private PayTypeApiService payTypeApiService;
    @Autowired
    private PayTypeService payTypeService;
    @Autowired
    private McenterMessageService mcenterMessageService;
    @Autowired
    private MallOrderApiService mallOrderApiService;
    @Autowired
    private MerchantPledgeApiService merchantPledgeApiService;


    @Resource
    AllyTicket21Mapper allyTicket21Mapper;
    @Resource
    AllyTicketJournal21Mapper allyTicketJournal21Mapper;
    @Resource
    MallOrderMapper mallOrderMapper;
    @Resource
    FundService fundService;
    @Autowired
    private AllyChannelMapper allyChannelMapper;
    @Autowired
    private PayChannelMapper payChannelMapper;
    @Resource
    private TransactionFundAccountChangePlanMapper fundAccountChangePlanMapper;


    /**
     * 兑换券使用
     */
    public static Short TICKET_STATUS_USE = 20;
    /**
     * 兑换券未使用
     */
    public static Short TICKET_STATUS_NO = 10;

    public static Short TICKET_STATUS_FRONZEN = 30;
    @Resource
    private FundAccountChangePlan21Mapper fundAccountChangePlan21Mapper;

    @Override
    public AppPayVO appPay(AppPayDTO dto) {

        //防重复提交
        if (commonService.repeatSubmit("appPay:" + dto.getUserBaseId())) {
            throw new UserBizException(BizCodeMessages.VALIDATOR_REPEAT_SUBMIT);
        }

        UserBase userBase = userBaseMapper.selectByPrimaryKey(dto.getUserBaseId());
        if (Objects.isNull(userBase)) {
            throw new UserBizException(BizCodeMessages.USER_NOT_EXISTS);
        }

        AppPayVO appPayVO = new AppPayVO();
        if (PayTypeEnum.WECHAT.isEquals(dto.getPayType())
                || PayTypeEnum.WECHAT_PROGRAM.isEquals(dto.getPayType())) {

            WechatPayDTO wechatPayDTO = new WechatPayDTO();
            wechatPayDTO.setIp(dto.getIp());
            wechatPayDTO.setOrderNo(dto.getOrderNo());
            wechatPayDTO.setPayFrom(dto.getPayFrom());
            wechatPayDTO.setPayType(dto.getPayType());
            wechatPayDTO.setAmount(new BigDecimal(dto.getAmount()));
            wechatPayDTO.setUserBaseId(dto.getUserBaseId());
            wechatPayDTO.setPlatNo(dto.getPlatNo());
            appPayVO.setWechatVo(wechatPay(wechatPayDTO));

        } else if (PayTypeEnum.ALIPAY.isEquals(dto.getPayType())) {

            AliPayDTO aliPayDTO = new AliPayDTO();
            aliPayDTO.setAmount(new BigDecimal(dto.getAmount()));
            aliPayDTO.setOrderNo(dto.getOrderNo());
            aliPayDTO.setPayFrom(dto.getPayFrom());
            aliPayDTO.setPayType(PayTypeEnum.ALIPAY.getCode());
            aliPayDTO.setPlatNo(dto.getPlatNo());
            aliPayDTO.setUserBaseId(dto.getUserBaseId());
            appPayVO.setAlipayVo(aliPay(aliPayDTO));

        } else if (PayTypeEnum.POINT.isEquals(dto.getPayType())) {

        } else if (PayTypeEnum.TICKET.isEquals(dto.getPayType())) {

            couponPayAlly(dto);

        } else if (PayTypeEnum.BALANCE.isEquals(dto.getPayType())) {

            balancePay(dto);

        } else if (PayTypeEnum.BALANCE_ALIPAY.isEquals(dto.getPayType())) {

            BigDecimal balanceAmount;
            BigDecimal amount;
            try {
                balanceAmount = new BigDecimal(dto.getBalanceAmount());
                amount = new BigDecimal(dto.getAmount());
            } catch (Exception e) {
                throw new UserBizException(BizCodeMessages.PARAMS_ERROR, "余额金额账户类型错误");
            }

            BigDecimal alipayAmount = amount.subtract(balanceAmount);
            if (alipayAmount.compareTo(BigDecimal.ZERO) <= 0) {
                throw new UserBizException(BizCodeMessages.PARAMS_ERROR, "余额金额、总金额参数错误");
            }

            // 冻结金额
            Result<FundPayBusVO> fundPayBusVOResult = balanceAliPay(dto);
            if (fundPayBusVOResult.isFail()) {
                throw new UserBizException(BizCodeMessages.UNKNOWN_ERROR, "资金冻结失败");
            }

            AliPayDTO aliPayDTO = new AliPayDTO();
            aliPayDTO.setAmount(alipayAmount);
            aliPayDTO.setOrderNo(dto.getOrderNo());
            aliPayDTO.setPayFrom(dto.getPayFrom());
            aliPayDTO.setPayType(PayTypeEnum.BALANCE_ALIPAY.getCode());
            aliPayDTO.setPlatNo(dto.getPlatNo());
            aliPayDTO.setUserBaseId(dto.getUserBaseId());
            appPayVO.setAlipayVo(aliPay(aliPayDTO));

        } else {
            throw new UserBizException(BizCodeMessages.WITHDRAW_PAY_TYPE_OFF);
        }
        return appPayVO;
    }

    /**
     * 余额支付-盟友钱包
     */
    private void balancePay(AppPayDTO dto) {

        AccountType toAccountType;
        if (AccountType.ALLY_V2.isEqualsFullAccountNo(dto.getAccountType())) {
            toAccountType = AccountType.SYS_V2_WITHDRAW;
        } else if (AccountType.ALLY_FROM_BOSS.isEqualsFullAccountNo(dto.getAccountType())) {
            toAccountType = AccountType.SYS_BOSS_WITHDRAW;
        } else {
            throw new UserBizException(BizCodeMessages.PARAMS_ERROR, "资金账户类型错误");
        }

        BigDecimal balanceAmount;
        BigDecimal amount;
        try {
            balanceAmount = new BigDecimal(dto.getBalanceAmount());
            amount = new BigDecimal(dto.getBalanceAmount());
        } catch (Exception e) {
            throw new UserBizException(BizCodeMessages.PARAMS_ERROR, "余额金额账户类型错误");
        }

        if (balanceAmount.subtract(amount).compareTo(BigDecimal.ZERO) != 0) {
            throw new UserBizException(BizCodeMessages.PARAMS_ERROR, "余额金额和总金额不一致");
        }

        Result<FundPayBusVO> result = new Result<>();

        FundAccountChangePlan changePlan = fundAccountChangePlanMapper.getByOrderId(PlatNoEnums.YXY.getCode(),
                dto.getOrderNo());

        if (Objects.isNull(changePlan)) {

            JournalInfoVO journalInfo = ChangeTypeConstant.getDepositJournalTypeV2(toAccountType, AccountMainJournalType.BALANCE_PAY);

            ChangeFundAccountV2DTO changeFundAccountV2DTO = new ChangeFundAccountV2DTO();
            changeFundAccountV2DTO.setPlatNo(PlatNoEnums.YXY.getCode());
            changeFundAccountV2DTO.setUserBaseId(dto.getUserBaseId());
            changeFundAccountV2DTO.setChangeAmount(balanceAmount);
            changeFundAccountV2DTO.setOrderNo(dto.getOrderNo());
            changeFundAccountV2DTO.setJournalInfo(journalInfo);
            changeFundAccountV2DTO.setChannelId(ChannelIdEnums.no.getCode());
            changeFundAccountV2DTO.setFundBillType(FundBillType.TYPE_300);

            result = fundService.deposit(changeFundAccountV2DTO);

        } else if (changePlan.getAccountChangePlanStatus().equals(ChangePlanStatus.CHANGING)) {

            // 解决下单未支付,此时资金已冻结的情况
            FundPayBusVO fundPayBusVO = new FundPayBusVO();
            fundPayBusVO.setFundAccountId(changePlan.getFundAccountId());
            fundPayBusVO.setInAmount(changePlan.getChangeAmount());
            fundPayBusVO.setFee(BigDecimal.ZERO);
            fundPayBusVO.setFundAccountChangePlanId(changePlan.getFundAccountChangePlanId());

        } else {
            throw new UserBizException(BizCodeMessages.UNKNOWN_ERROR, "资金冻结失败");
        }

        if (result.isFail()) {
            throw new UserBizException(BizCodeMessages.UNKNOWN_ERROR, "资金冻结失败");
        }

        Result undepositResults = fundService.undepositByFundAccountChangePlanId(result.getData().getFundAccountChangePlanId(), PlatNoEnums.YXY.getCode());
        if (undepositResults.isFail()) {
            KLog.error("资金解冻失败,参数:{}", result);
            return;
        }

        PayAttachParamDTO payAttachParamDTO = new PayAttachParamDTO();
        payAttachParamDTO.setPayType(PayTypeEnum.BALANCE.getCode());
        payAttachParamDTO.setPayAmt(balanceAmount);
        payAttachParamDTO.setPayFrom(dto.getPayFrom());

        doSuccNotice(dto.getOrderNo(), dto.getOrderNo(), payAttachParamDTO);
    }

    /**
     * 余额+阿里支付
     */
    private Result<FundPayBusVO> balanceAliPay(AppPayDTO dto) {

        AccountType toAccountType;
        if (AccountType.ALLY_V2.isEqualsFullAccountNo(dto.getAccountType())) {
            toAccountType = AccountType.SYS_V2_WITHDRAW;
        } else if (AccountType.ALLY_FROM_BOSS.isEqualsFullAccountNo(dto.getAccountType())) {
            toAccountType = AccountType.SYS_BOSS_WITHDRAW;
        } else {
            throw new UserBizException(BizCodeMessages.PARAMS_ERROR, "资金账户类型错误");
        }

        Result<FundPayBusVO> result = new Result<>();

        FundAccountChangePlan changePlan = fundAccountChangePlanMapper.getByOrderId(PlatNoEnums.YXY.getCode(),
                dto.getOrderNo());

        if (Objects.isNull(changePlan)) {

            JournalInfoVO journalInfo = ChangeTypeConstant.getDepositJournalTypeV2(toAccountType, AccountMainJournalType.BALANCE_PAY);

            ChangeFundAccountV2DTO changeFundAccountV2DTO = new ChangeFundAccountV2DTO();
            changeFundAccountV2DTO.setPlatNo(PlatNoEnums.YXY.getCode());
            changeFundAccountV2DTO.setUserBaseId(dto.getUserBaseId());
            changeFundAccountV2DTO.setChangeAmount(new BigDecimal(dto.getBalanceAmount()));
            changeFundAccountV2DTO.setOrderNo(dto.getOrderNo());
            changeFundAccountV2DTO.setJournalInfo(journalInfo);
            changeFundAccountV2DTO.setChannelId(ChannelIdEnums.no.getCode());
            changeFundAccountV2DTO.setFundBillType(FundBillType.TYPE_300);

            return fundService.deposit(changeFundAccountV2DTO);

        } else if (changePlan.getAccountChangePlanStatus().equals(ChangePlanStatus.CHANGING)) {

            // 解决下单未支付,此时资金已冻结的情况
            FundPayBusVO fundPayBusVO = new FundPayBusVO();
            fundPayBusVO.setFundAccountId(changePlan.getFundAccountId());
            fundPayBusVO.setInAmount(changePlan.getChangeAmount());
            fundPayBusVO.setFee(BigDecimal.ZERO);
            fundPayBusVO.setFundAccountChangePlanId(changePlan.getFundAccountChangePlanId());

            result.setData(fundPayBusVO);

            return result;
        }

        return Result.builder().fail();
    }

    /**
     * 兑换券支付
     */
    private void couponPayAlly(AppPayDTO dto) {
        UserBase userBase = userBaseMapper.selectByPrimaryKey(dto.getUserBaseId());
        if (userBase == null) {
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING);
        }

        //查询可使用兑换券张数
        AllyTicket21Example allyTicket21Example = new AllyTicket21Example();
        allyTicket21Example.createCriteria().andUserBaseIdEqualTo(userBase.getUserBaseId())
                .andTicketExpirationTimeGreaterThan(LocalDateTime.now()).andTicketStatusEqualTo(TICKET_STATUS_NO);
        allyTicket21Example.setOrderByClause("ticket_expiration_time asc limit " + Integer.parseInt(dto.getAmount()));
        List<AllyTicket21> allyTicket21s = allyTicket21Mapper.selectByExample(allyTicket21Example);

        if (CollectionUtils.isEmpty(allyTicket21s)) {
            throw new UserBizException(BizCodeMessages.TRANSACTION_TICKET_NONE);
        }

        if (allyTicket21s.size() < Integer.parseInt(dto.getAmount())) {
            throw new UserBizException(BizCodeMessages.MALL_ORDER_STATUS_ERR);
        }

        //短息校验
//        CheckVerificationCodeV2DTO verificationCodeDTO = new CheckVerificationCodeV2DTO();
//        verificationCodeDTO.setCode(dto.getMsgCode());
//        verificationCodeDTO.setMsgType(MsgType.ticket);
//        verificationCodeDTO.setPhone(userBase.getPhone());
//        verificationCodeDTO.setPlatNo(dto.getPlatNo());
//        Result<Void> verifyResult = mcenterMessageService.checkVerificationCodeV2(verificationCodeDTO);
//        if (!verifyResult.isSuccess()) {
//            throw new UserBizException(BizCodeMessages.USER_LOGIN_MOBILE_CODE_ERR);
//        }

        MallOrderExample orderExample = new MallOrderExample();
        orderExample.createCriteria().andOrderNoEqualTo(dto.getOrderNo());
        List<MallOrder> mallOrders = mallOrderMapper.selectByExample(orderExample);

        short orderStatus = mallOrders.get(0).getStatus();
        if (!MallOrderEnum.StatusEnum.status_10.isEquals(orderStatus)) {
            log.error("订单状态错误，" + orderStatus);
            throw new UserBizException(BizCodeMessages.ORDER_STATUS_ERR, "订单状态错误，" + orderStatus);
        }

        short exchangeChannel = mallOrders.get(0).getExchangeChannel();
        if (exchangeChannel == MallOrderEnum.ExchangeChannelEnum.exchangeChannel_20.getCode().intValue()) {
            //向机构兑换冻结兑换券
            for (AllyTicket21 ticket : allyTicket21s) {
                AllyTicket21 allyTicket21 = new AllyTicket21();
                allyTicket21.setAllyTicketId(ticket.getAllyTicketId());
                allyTicket21.setTicketStatus(TICKET_STATUS_FRONZEN);
                allyTicket21.setOrderNo(dto.getOrderNo());
                allyTicket21Mapper.updateByPrimaryKeySelective(allyTicket21);
            }
        } else {
            //向平台兑换变更兑换券状态
            for (AllyTicket21 ticket : allyTicket21s) {
                AllyTicket21 allyTicket21 = new AllyTicket21();
                allyTicket21.setAllyTicketId(ticket.getAllyTicketId());
                allyTicket21.setTicketStatus(TICKET_STATUS_USE);
                allyTicket21.setOrderNo(dto.getOrderNo());
                allyTicket21Mapper.updateByPrimaryKeySelective(allyTicket21);
            }
        }

        //查询兑换券流水
        AllyTicketJournal21Example allyTicketJournal21Example = new AllyTicketJournal21Example();
        allyTicketJournal21Example.createCriteria().andToUserBaseIdEqualTo(dto.getUserBaseId());
        allyTicketJournal21Example.setOrderByClause("ally_ticket_journal_id desc limit 1");
        List<AllyTicketJournal21> allyTicketJournal21s = allyTicketJournal21Mapper.selectByExample(allyTicketJournal21Example);

        //保存积分兑换券流水
        AllyTicketJournal21 allyTicketJournal21 = new AllyTicketJournal21();
        allyTicketJournal21.setToUserBaseId(allyTicketJournal21s.get(0).getToUserBaseId());
        allyTicketJournal21.setToUserName(allyTicketJournal21s.get(0).getToUserName());
        allyTicketJournal21.setJournalName(AllyTicketEnum.TicketJournalTypeEnum.USE.getMsg());
        allyTicketJournal21.setJournalType(AllyTicketEnum.TicketJournalTypeEnum.USE.getCode());
        allyTicketJournal21.setChangeValue(Integer.parseInt(dto.getAmount()));
        allyTicketJournal21.setTicketAmountBefore(allyTicketJournal21s.get(0).getTicketAmountAfter());
        allyTicketJournal21.setTicketAmountAfter(allyTicketJournal21s.get(0).getTicketAmountAfter() - Integer.parseInt(dto.getAmount()));
        allyTicketJournal21.setOrderNo(dto.getOrderNo());
        allyTicketJournal21.setChannelId(dto.getChannelId());
        allyTicketJournal21.setPlatNo(dto.getPlatNo());
        allyTicketJournal21.setCreateMonth(LocalDateUtils.nowByFormat(DateFormat.DATE_MONTH.getPartten()));
        int i1 = allyTicketJournal21Mapper.insertSelective(allyTicketJournal21);
        BizAssertUtils.assertOne(i1, "插入积分兑换券流水失败");

        PayAttachParamDTO payAttachParamDTO = new PayAttachParamDTO();
        payAttachParamDTO.setPayType(PayTypeEnum.TICKET.getCode());
        payAttachParamDTO.setPayAmt(new BigDecimal(dto.getAmount()));
        payAttachParamDTO.setPayFrom(dto.getPayFrom());
        doSuccNotice(dto.getOrderNo(), dto.getOrderNo(), payAttachParamDTO);
    }

    private WxAppPayOrderVO wechatPay(WechatPayDTO dto) {
        KLog.info("【微信app支付】平台入参:{}", dto.toJSON());

        //非生产环境
        if (!commonService.isProd()) {
            dto.setAmount(new BigDecimal("0.01"));
        }

        Map<String, String> map = payTypeApiService.getPayParams(PayTypeEnum.getPayType(dto.getPayType()), PayFromEnum.getPayFrom(dto.getPayFrom()));
        WxPayService wxPayService = payTypeService.getWxPayService(PayFromEnum.getPayFrom(dto.getPayFrom()));
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setBody(PayAccountConfig.formatAppPayBody(dto.getPlatNo()));
        request.setOutTradeNo(dto.getOrderNo());
        request.setTotalFee(dto.getAmount().multiply(new BigDecimal("100")).intValue());   //单位分
        request.setSpbillCreateIp(dto.getIp());
        request.setNotifyUrl(map.get("notifyurl"));

        if (PayTypeEnum.WECHAT_PROGRAM.isEquals(dto.getPayType())) {
            request.setTradeType("JSAPI");
            request.setOpenid("");  //暂不支持小程序支付
        } else {
            request.setTradeType("APP");
        }

        //附加参数
        PayAttachParamDTO attachParam = new PayAttachParamDTO();
        attachParam.setPlatNo(dto.getPlatNo());
        attachParam.setPayFrom(dto.getPayFrom());
        attachParam.setPayType(dto.getPayType());
        request.setAttach(attachParam.toJSON());
        try {
            KLog.info("【微信app支付】组织数据:{}", JSON.toJSONString(request));
            Object orderResult = wxPayService.createOrder(request);
            KLog.info("【微信app支付】微信返回:{}", JSON.toJSONString(orderResult));
            WxAppPayOrderVO result = new WxAppPayOrderVO();
            BeanUtils.copyProperties(orderResult, result);
            return result;
        } catch (WxPayException e) {
            KLog.error("【微信app支付】微信支付失败:{}", e.getMessage(), e);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, e.getMessage());
        }
    }

    private WxPayOrderQueryResult wechatTradeQuery(TradeQueryDTO queryDTO) throws WichdrawFailException {

        WxPayService wxPayService = payTypeService.getWxPayService(PayFromEnum.getPayFrom(queryDTO.getPayFrom()));

        WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
        request.setOutTradeNo(queryDTO.getOrderNO());

        try {
            KLog.info("【微信订单查询】组织数据:{},入参:{}", JSON.toJSONString(request), queryDTO.toJSON());
            WxPayOrderQueryResult result = wxPayService.queryOrder(request);
            KLog.info("【微信订单查询】微信返回:{},入参:{}", JSON.toJSONString(result), queryDTO.toJSON());

            if (!StringUtils.equals(result.getResultCode(), "SUCCESS")) {
                KLog.warn("【微信订单查询】微信查询未成功,微信返回:{}, 组织数据:{}", JSON.toJSONString(result), JSON.toJSONString(request));
                throw new WichdrawFailException("微信查询未成功,微信返回:" + JSON.toJSONString(result) + ", 组织数据:" + JSON.toJSONString(request));
            }

            if (!StringUtils.equals(result.getTradeState(), "SUCCESS")) {
                KLog.warn("【微信订单查询】微信支付未成功,微信返回:{}, 组织数据:{}", JSON.toJSONString(result), JSON.toJSONString(request));
                throw new WichdrawFailException("微信支付未成功,微信返回:" + JSON.toJSONString(result) + ", 组织数据:" + JSON.toJSONString(request));
            }
            return result;
        } catch (WxPayException e) {
            KLog.warn("【微信订单查询】微信查询失败, {}, 入参{}", e.getMessage(), queryDTO.toJSON(), e);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "微信查询失败," + e.getMessage());
        }
    }

    private String aliPay(AliPayDTO dto) {
        KLog.info("【支付宝app支付】入参:{}", dto.toJSON());

        //非生产环境
        if (!commonService.isProd()) {
            dto.setAmount(new BigDecimal("0.01"));
        }

        // 查询盟友的庄家支付宝账号
        Map<String, String> map = getPayParamsFromAliBanker(dto.getUserBaseId(), dto.getPayFrom());
        if (Objects.isNull(map) || map.isEmpty()) {
            log.error("未获取到支付宝参数, dto={}", dto.toJSON());
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "未获取到支付宝参数");
        }

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(PayAccountConfig.formatAppPayBody(dto.getPlatNo()));                    //对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body
        model.setSubject(PayAccountConfig.formatAppPayBody(dto.getPlatNo()));                 //商品的标题/交易标题/订单标题/订单关键字等
        NumberFormat nf = new DecimalFormat("##.##");
        model.setTotalAmount(nf.format(dto.getAmount()));  //订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
        model.setProductCode("QUICK_MSECURITY_PAY");    //销售产品码，商家和支付宝签约的产品码
        model.setOutTradeNo(dto.getOrderNo());          //商户网站唯一订单号，请保证OutTradeNo值每次保证唯一
        model.setTimeoutExpress("30m");                 //该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        model.setEnablePayChannels("balance,moneyFund,pcredit,creditCard,creditCardExpress,debitCardExpress");

        //附加参数
        PayAttachParamDTO attachParam = new PayAttachParamDTO();
        attachParam.setPlatNo(dto.getPlatNo());
        attachParam.setPayFrom(dto.getPayFrom());
        attachParam.setPayType(dto.getPayType());
        attachParam.setPayChannelId(map.get("payChannelId"));
        model.setPassbackParams(attachParam.toJSON());

        request.setBizModel(model);
        request.setNotifyUrl(map.get("notifyurl"));             //商户外网可以访问的异步地址

        AlipayClient alipayClient = payTypeService.getAlipayClientByParamMap(map);
        AlipayTradeAppPayResponse response;
        try {
            response = alipayClient.sdkExecute(request);    //这里和普通的接口调用不同，使用的是sdkExecute
            KLog.info("【支付宝app支付】返回:{},入参:{}", response.getBody(), dto.toJSON());
            return response.getBody();                      //就是orderString 可以直接给客户端请求，无需再做处理。
        } catch (AlipayApiException e) {
            KLog.error("【支付宝app支付】异常:{}", e.getMessage(), e);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, e.getMessage());
        }
    }


    /**
     * 查询用户上级庄家的支付宝参数
     *
     * @param userBaseId 支付用户id
     * @param payForm    支付场景，仅采购
     * @return 支付需要的参数
     */
    public Map<String, String> getPayParamsFromAliBanker(String userBaseId, String payForm) {
        Map<String, String> map = null;
        // 仅采购
        if (PayFromEnum.yxy_purchase.isEquals(payForm)) {
            String bankerUserBaseId = getBankerId(userBaseId);
            if (StringUtils.isNotBlank(bankerUserBaseId)) {
                PayChannelExample example = new PayChannelExample();
                example.createCriteria().andBankerUserBaseIdEqualTo(bankerUserBaseId).andNameLike("支付宝%");
                List<PayChannel> payChannelList = payChannelMapper.selectByExample(example);
                if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(payChannelList)) {
                    Integer payChannelId = payChannelList.get(0).getPayChannelId();
                    log.info("getPayParamsFromAliBanker,bankerUserBaseId={},payChannel={}", bankerUserBaseId, payChannelId);
                    map = payTypeApiService.getPayParamsByChannel(payChannelId);

                    // 用于支付宝回调时方便查询参数 验签
                    map.put("payChannelId", String.valueOf(payChannelId));
                }
            }
        }
        if (Objects.isNull(map) || map.isEmpty()) {
            log.error("未获取到庄家的支付宝参数，取平台参数, uid={}", userBaseId);
            map = payTypeApiService.getPayParams(PayTypeEnum.ALIPAY, PayFromEnum.getPayFrom(payForm));
        }
        return map;
    }


    /**
     * 查询庄家id
     *
     * @param userBaseId
     * @return
     */
    private String getBankerId(String userBaseId) {
        AllyChannelExample example = new AllyChannelExample();
        example.createCriteria().andUserBaseIdEqualTo(userBaseId);
        List<AllyChannel> allyChannelList = allyChannelMapper.selectByExample(example);
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(allyChannelList)) {
            return allyChannelList.get(0).getTeamUserBaseId();
        }
        return null;
    }


    public AlipayTradeQueryResponse aliTradeQuery(TradeQueryDTO queryDTO) throws WichdrawFailException {
        AlipayClient alipayClient = payTypeService.getAlipayClient(PayFromEnum.getPayFrom(queryDTO.getPayFrom()));
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryBiz queryBiz = new AlipayTradeQueryBiz();
        queryBiz.setOut_trade_no(queryDTO.getOrderNO());
        request.setBizContent(queryBiz.toJSON());
        try {
            KLog.info("【支付宝交易查询】请求参数:{},入参:{}", JSON.toJSONString(request), queryDTO.toJSON());
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            KLog.info("【支付宝交易查询】支付宝响应:{}, 入参:{}", JSON.toJSONString(response), queryDTO.toJSON());
            if (response == null) {
                KLog.warn("【支付宝交易查询处理】支付宝无响应");
                throw new WichdrawWaitException("支付宝无响应");
            }
            if (!response.isSuccess()) {
                KLog.warn("【支付宝交易查询】交易未成功,{}", response.getSubMsg());
                throw new WichdrawFailException(response.getSubMsg());
            }
            // 交易成功
            if (!(AlipayProperties.TradeStatus.TRADE_FINISHED.value().equals(response.getTradeStatus())
                    || AlipayProperties.TradeStatus.TRADE_SUCCESS.value().equals(response.getTradeStatus()))) {
                KLog.warn("【支付宝交易查询】交易状态未成功,{}", response.getSubMsg());
                throw new WichdrawFailException(response.getSubMsg());
            }
            return response;
        } catch (AlipayApiException e) {
            KLog.warn("【支付宝交易查询处理】查询失败, {}, 入参{}", e.getMessage(), queryDTO.toJSON(), e);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "支付宝交易查询失败," + e.getMessage());
        }

    }

    @Override
    public void wechatNotify(String param) {
        KLog.info("【微信app支付通知】入参:{}", param);

        try {

            //验签 + 状态判断
            final WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(param);
            KLog.info("【微信app支付通知】解析支付结果:{},入参:{}", JSON.toJSONString(result), param);
            PayAttachParamDTO attachParamDTO = JSON.parseObject(result.getAttach(), PayAttachParamDTO.class);

            WxPayService wxPayService = payTypeService.getWxPayService(PayFromEnum.getPayFrom(attachParamDTO.getPayFrom()));
            result.checkResult(wxPayService, wxPayService.getConfig().getSignType(), true);

            if (StringUtils.isBlank(result.getOutTradeNo())) {
                KLog.warn("【微信app支付通知】未获取到订单号号,入参:{}", param);
                throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "未获取到商户号");
            }

            BigDecimal payAmt = new BigDecimal(String.valueOf(result.getTotalFee())).divide(new BigDecimal("100"));

            attachParamDTO.setPayAmt(payAmt);
            attachParamDTO.setPayType(PayTypeEnum.WECHAT.getCode());
            doSuccNotice(result.getOutTradeNo(), result.getTransactionId(), attachParamDTO);

        } catch (WxPayException e) {
            KLog.error("【微信app支付通知】异常:{},入参:{}", e.getMessage(), param, e);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, e.getMessage());
        }
    }

    @Override
    public void aliNotify(Map<String, String[]> requestParams) {

        KLog.info("【阿里app支付通知】入参:{}", JSON.toJSONString(requestParams));

        //获取支付宝POST过来反馈信息
        Map<String, String> notifyParams = new HashMap<>();
        for (String o : requestParams.keySet()) {
            String[] values = requestParams.get(o);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            notifyParams.put(o, valueStr);
        }

        String tradeStatus = notifyParams.get("trade_status");
        if (StringUtils.isBlank(tradeStatus)) {
            KLog.warn("【阿里app支付通知】未获取到交易状态,入参:{}", notifyParams);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "未获取到交易状态");
        }

        // 交易失败
        if (!AlipayProperties.TradeStatus.TRADE_FINISHED.value().equals(tradeStatus)
                && !AlipayProperties.TradeStatus.TRADE_SUCCESS.value().equals(tradeStatus)) {
            KLog.warn("【阿里app支付通知】交易未成功,入参:{}", notifyParams);
            return;
        }

        String payAttachParam = notifyParams.get("passback_params");
        PayAttachParamDTO attachParamDTO = JSON.parseObject(payAttachParam, PayAttachParamDTO.class);
        //验签
        if (!aliVerifyRsa(notifyParams, attachParamDTO)) {
            KLog.warn("【阿里app支付通知】验签失败,入参:{}", notifyParams);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "验签失败");
        }


        String orderNo = notifyParams.get("out_trade_no");
        if (StringUtils.isBlank(orderNo)) {
            KLog.warn("【阿里app支付通知】未获取到订单号,入参:{}", notifyParams);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "未获取到商户号");
        }


        String serialNo = notifyParams.get("trade_no");
        if (notifyParams.get("buyer_pay_amount") != null) {
            BigDecimal payAmt = new BigDecimal(notifyParams.get("buyer_pay_amount"));
            attachParamDTO.setPayAmt(payAmt);
        }

        doSuccNotice(orderNo, serialNo, attachParamDTO);

    }

    //阿里app支付通知校验签名
    private Boolean aliVerifyRsa(Map<String, String> params, PayAttachParamDTO attachParamDTO) throws UserBizException {
        try {
            Map<String, String> map;
            String payChannelId = attachParamDTO.getPayChannelId();
            if (PayFromEnum.yxy_purchase.isEquals(attachParamDTO.getPayFrom()) && StringUtils.isNotBlank(payChannelId)) {
                // 查询庄家的支付宝参数
                map = payTypeApiService.getPayParamsByChannel(Integer.parseInt(payChannelId));
            } else {
                map = payTypeApiService.getPayParams(PayTypeEnum.ALIPAY, PayFromEnum.getPayFrom(attachParamDTO.getPayFrom()));
            }
            //是否 证书加签
            if (StringUtils.isNotBlank(map.get("alipayCertPath"))) {
                String basePath = payTypeService.queryAlipayCertPath(map);
                String certPath = basePath + map.get("alipayCertPath");
                log.debug("【阿里app支付通知】使用证书验签, 证书地址:{}", certPath);
                return AlipaySignature.rsaCertCheckV1(params, certPath, "utf-8", "RSA2");
            }

            return AlipaySignature.rsaCheckV1(
                    params,
                    map.get("pubkey"),
                    "UTF-8", "RSA2");
        } catch (AlipayApiException e) {
            KLog.error("【阿里app支付通知】校验签名异常", e);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, e.getMessage());
        }
    }

    /**
     * 支付成功处理
     *
     * @param orderNo        订单号
     * @param serialNo       通道交易号
     * @param attachParamDTO 附加参数
     */
    private void doSuccNotice(String orderNo, String serialNo, PayAttachParamDTO attachParamDTO) {

        KLog.info("【支付成功处理】订单号:{}, 流水号:{}, 附加参数:{}", orderNo, serialNo, attachParamDTO.toJSON());
        if (PayFromEnum.yxy_deposit.isEquals(attachParamDTO.getPayFrom())) {    //交押金

            DepositNoticeDTO depositNoticeDTO = new DepositNoticeDTO();
            depositNoticeDTO.setPayType(attachParamDTO.getPayType());
            depositNoticeDTO.setPayFrom(attachParamDTO.getPayFrom());
            depositNoticeDTO.setPlatNo(attachParamDTO.getPlatNo());
            depositNoticeDTO.setOrderNo(orderNo);
            depositNoticeDTO.setSerialNo(serialNo);
            depositNoticeDTO.setPayAmount(attachParamDTO.getPayAmt());
            merchantPledgeApiService.depositNotice(depositNoticeDTO);

        } else if (PayFromEnum.yxy_purchase.isEquals(attachParamDTO.getPayFrom())
                || PayFromEnum.yxy_merchant_purchase.isEquals(attachParamDTO.getPayFrom())) {        //采购机具

            if (PayTypeEnum.BALANCE_ALIPAY.isEquals(attachParamDTO.getPayType())) {

                // 对于余额支付宝支付,由于部分使用余额支付,需要先进行解冻
                FundAccountChangePlan21Example fundAccountChangePlan21Example = new FundAccountChangePlan21Example();
                fundAccountChangePlan21Example.createCriteria().andOrderIdEqualTo(orderNo);
                List<FundAccountChangePlan21> fundAccountChangePlan21s = fundAccountChangePlan21Mapper.selectByExample(fundAccountChangePlan21Example);
                if (fundAccountChangePlan21s.isEmpty()) {
                    KLog.error("余额阿里支付,解冻失败,订单号:{}", orderNo);
                    throw new SysBizException(BizCodeMessages.UNKNOWN_ERROR, "余额阿里支付,解冻失败");
                }

                Result result = fundService.undepositByFundAccountChangePlanId(fundAccountChangePlan21s.get(0).getFundAccountChangePlanId(), PlatNoEnums.YXY.getCode());
                if (result.isFail()) {
                    KLog.error("余额阿里支付,解冻失败,订单号:{}", orderNo);
                    throw new SysBizException(BizCodeMessages.UNKNOWN_ERROR, "余额阿里支付,解冻失败");
                }
            }

            MallOrderPaySuccessUpdateDTO orderPaySuccessUpdateDTO = new MallOrderPaySuccessUpdateDTO();
            orderPaySuccessUpdateDTO.setOrderNo(orderNo);
            orderPaySuccessUpdateDTO.setPayType(attachParamDTO.getPayType());
            orderPaySuccessUpdateDTO.setPaySuccessTime(LocalDateTime.now());
            orderPaySuccessUpdateDTO.setTransactionId(serialNo);
            orderPaySuccessUpdateDTO.setPayAmount(attachParamDTO.getPayAmt());
            orderPaySuccessUpdateDTO.setSign(AesEncryptUtil.base64AesEncrypt(orderNo));
            Result succResult = mallOrderApiService.onPaySuccess(orderPaySuccessUpdateDTO);
            if (!succResult.isSuccess()) {
                KLog.warn("【支付成功处理】采购机具,处理异常,响应:{},传参:{}", succResult, orderPaySuccessUpdateDTO.toString());
            }

        } else if (PayFromEnum.yxy_topup.isEquals(attachParamDTO.getPayFrom())) {           //充值

            //TODO 2024-06-20 充值功能废弃,不允许充值
//            dealTopup(orderNo, serialNo, attachParamDTO);
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "不支持的支付场景");

        } else {
            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "不支持的支付场景");
        }
    }

    /**
     * 创建充值订单
     */
    public ToPupVO createToPupOrder(ToPupDTO dto) {

        UserBase userBase = userBaseMapper.selectByPrimaryKey(dto.getUserBaseId());

        PayThreeParties payThreeParties = PayThreeParties.builder()
                .userBaseId(dto.getUserBaseId())
                .realName(userBase != null ? userBase.getUserName() : null)
                .orderNo(PayAccountConfig.getOrderPrefix(dto.getPayFrom()) + DateFormat.DATETIME_MILLISECOND_COMPACT.format(LocalDateTime.now()) + RandomStringUtils.randomNumeric(5))
                .amount(new BigDecimal(dto.getAmount()))
                .status(PayThreePartiesEnum.STATUS_INIT.getCode())
                .payFrom(dto.getPayFrom())
                .channelId(dto.getChannelId())
                .platNo(dto.getPlatNo())
                .build();
        int inPay = payThreePartiesMapper.insertSelective(payThreeParties);
        BizAssertUtils.assertOne(inPay, "插入支付订单失败");

        ToPupVO toPupVO = new ToPupVO();
        toPupVO.setOrderNo(payThreeParties.getOrderNo());
        return toPupVO;
    }

    /**
     * 充值成功处理
     * 已弃用,
     */
    @Deprecated
    private void dealTopup(String orderNo, String serialNo, PayAttachParamDTO attachParamDTO) {
//        PayThreePartiesExample payThreePartiesExample = new PayThreePartiesExample();
//        payThreePartiesExample.createCriteria().andOrderNoEqualTo(orderNo).andIsDelEqualTo(false);
//        List<PayThreeParties> payThreePartiesList = payThreePartiesMapper.selectByExample(payThreePartiesExample);
//        if (CollectionUtils.isEmpty(payThreePartiesList)) {
//            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "未找到支付订单");
//        }
//        PayThreeParties payThreeParties = payThreePartiesList.get(0);
//
//        if (commonService.isProd() && payThreeParties.getAmount().compareTo(attachParamDTO.getPayAmt()) != 0) {
//            throw new UserBizException(BizCodeMessages.TRANSACTION_PLEDGE_CHECKING, "付款金额不一致");
//        }
//
//        PayThreeParties upParties = new PayThreeParties();
//        upParties.setPayThreePartiesId(payThreeParties.getPayThreePartiesId());
//        upParties.setThirdOrderNo(serialNo);
//        upParties.setPayType(attachParamDTO.getPayType());
//        upParties.setRealAmount(attachParamDTO.getPayAmt());
//        upParties.setStatus(PayThreePartiesEnum.STATUS_SUCC.getCode());
//        int upPartiesCC = payThreePartiesMapper.updateByPrimaryKeySelective(upParties);
//        BizAssertUtils.assertOne(upPartiesCC, "更新支付订单失败");
//
//        ChangeFundAccountDTO changeFundAccountDTO = new ChangeFundAccountDTO();
//        changeFundAccountDTO.setUserBaseId(payThreeParties.getUserBaseId());
//        changeFundAccountDTO.setFundBillType(FundBillType.TYPE_100);
//        changeFundAccountDTO.setChangeAmount(payThreeParties.getAmount());
//        changeFundAccountDTO.setSysAccountType(PayAccountConfig.formatSysAccountType(payThreeParties.getPayFrom(), payThreeParties.getPlatNo()));
//        changeFundAccountDTO.setUserAccountType(PayAccountConfig.formatUserAccountType(payThreeParties.getPayFrom(), payThreeParties.getPlatNo()));
//        changeFundAccountDTO.setChannelId(payThreeParties.getChannelId());
//        changeFundAccountDTO.setPlatNo(payThreeParties.getPlatNo());
//        changeFundAccountDTO.setOrderNo(payThreeParties.getOrderNo());
//
//        changeFundAccountDTO.setAccountMainJournalType(AccountMainJournalType.RECHARGE.getCode());
//
//        fundAccountOptService.addFundAccount(changeFundAccountDTO);
    }

    /**
     * 查询是否支付成功
     */
    @Override
    public Boolean tradeQuery(TradeQueryDTO queryDTO) {
        KLog.info("【支付查询】入参:{}", queryDTO.toJSON());
        try {
            if (PayTypeEnum.WECHAT.isEquals(queryDTO.getPayType())) {
                wechatTradeQuery(queryDTO);
            } else if (PayTypeEnum.ALIPAY.isEquals(queryDTO.getPayType())) {
                aliTradeQuery(queryDTO);
            } else {
                return false;
            }
        } catch (Exception e) {
            KLog.info("【支付查询】订单未支付,{},入参:{}", e.getMessage(), queryDTO.toJSON());
            return false;
        }
        KLog.info("【支付查询】订单已支付,入参:{}", queryDTO.toJSON());
        return true;
    }

    @Override
    public Result aliTradeRefund(TradeRefundDTO refundDTO) {

        KLog.info("【支付宝退款】入参:{}", refundDTO.toJSON());

        AlipayClient alipayClient = payTypeService.getAlipayClientByChannel(refundDTO.getPayChannel());
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
        refundModel.setOutTradeNo(refundDTO.getOrderNo());
        refundModel.setRefundAmount(String.valueOf(refundDTO.getAmt()));
        request.setBizModel(refundModel);

        AlipayTradeRefundResponse response = new AlipayTradeRefundResponse();
        try {
            KLog.info("【支付宝退款】请求参数:{},入参:{}", JSON.toJSONString(request), refundDTO.toJSON());
            response = alipayClient.certificateExecute(request);
            KLog.info("【支付宝退款】返回:{},入参:{}", JSON.toJSONString(response), refundDTO.toJSON());
            if (!response.isSuccess()) {
                KLog.error("【支付宝退款】支付宝返回未成功,支付宝返回:{},入参:{}", JSON.toJSONString(response), refundDTO.toJSON());
                return Result.builder().fail(BizCodeMessages.ALIPAY_RESPONSE_FAIL, response);
            }
        } catch (AlipayApiException e) {
            KLog.error("【支付宝退款】异常,{},入参:{}", e.getErrMsg(), refundDTO.toJSON(), e);
            return Result.builder().fail(BizCodeMessages.ALIPAY_RESPONSE_FAIL, e.getErrMsg());
        }
        return Result.builder().success(response.getTradeNo());
    }

}
